package com.qq.文件_io_字符.字符集;

import java.io.FileWriter;

//字符集（Character Set）是多个字符的集合，字符集种类较多，每个字符集包含的字符个数不同，常见字符集有：  
//ASCII字符集：
//ASCII(American Standard Code for Information Interchange，美国信息交换标准代码)
//ASCII使用1个字节存储一个字符，一个字节是8位，最高位符号位为0，总共可以表示128个字符信息，
//对于表示英文、数字、符号。来说是够用,所有编码标准都兼容ASCII码，它在所有编码标准里都只占1个字节

//GBK字符集:
//GBK是中国的码表，包含了几万个汉字等字符，由区位码转换而来，同时也要兼容ASCII编码。
//GBK编码中一个中文字符一般以两个字节的形式存储。为了与ASCII码区别，每个字节的首位都是1.

//Unicode字符集：
//统一码，也叫万国码。是计算机科学领域里的一项业界标准，UTF-8是Unicode的一种常见编码方式。
//UTF-8和UTF-16的区别主要区别在于它需要多少字节来表示内存中的字符，
//UTF-8 最少使用 1 个字节，而 UTF-16 最少使用 2 个字节（所以UTF-16不兼容ASCII）
//UTF-8编码后一个中文一般以三个字节的形式存储，同时也要兼容ASCII编码表。
//技术人员都应该使用UTF-8的字符集编码。
//UTF-8是一种变长字节编码方式。对于某一个字符的UTF-8编码，如果只有一个字节则其最高二进制位为0；如果是
//多字节，其第一个字节从最高位开始，连续的二进制位值为1的个数决定了其编码的位数，其余各字节均以10开头。
	
//注意：字符解码时使用的字符集和编码时使用的字符集必须一致，否则会出现乱码，
//编码解码步骤：
//编码：输入一段文字输入 -> 查询Unicode码表中对应的数字（16进制）  -> 通过UTF-8的方案转换成二进制 -> 存到计算机
//解码：将二进制代码通过UTF-8解码成对应16进制数字 ->查询Unicode码表中对应的字符 ->将文字展示到计算机

//编码：输入一段文字输入 -> 查询GBK码表中对应的数字（16进制）  -> 通过GBK将其转换成二进制 -> 存到计算机
//解码：将二进制代码通过GBK编码成对应16进制数字->查询GBK码表中对应的字符 ->将文字展示到计算机

//注意：英文和数字在任何国家的编码中都不会乱码，因为所有的字符集都兼容ASCII码
//注：io流 read()方法返回的是Unicode的十进制编码，0到65535

import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

//编码方法：将字符串转为字节数组
//byte[] getBytes​()		
//使用平台的默认字符集将该 String编码为一系列字节，将结果存储到新的字节数组中
//byte[] getBytes​(String charsetName)
//使用指定的字符集将该 String编码为一系列字节，将结果存储到新的字节数组中 

//解码方法：将字节数组转为字符串
//String​(byte[] bytes)
//通过使用平台的默认字符集解码指定的字节数组来构造新的 String
//String​(byte[] bytes, String charsetName)
//通过指定的字符集解码指定的字节数组来构造新的 String

//编码：真实字符与二进制串（1字节）的对应关系，真实字符→二进制串
//解码：二进制串（1字节）与真实字符的对应关系，二进制串→真实字符

//UTF-8编码方式：英文字母、数字占1个字节兼容(ASCII编码)、一个汉字占3个字节
//GBK编码方式：英文字母、数字占1个字节兼容(ASCII编码)，1个汉字占用2个字节

//注：window文件 【另存为】 可以改变文件码表 

	/*
目标：学会自己进行文字的编码和解码，为以后可能用到的场景做准备。
*/
public class Test {
    public static void main(String[] args) throws Exception {
        // 1、编码：把文字转换成字节（使用指定的编码）
        String name = "abc我爱你中国";
//         byte[] bytes = name.getBytes(); // 以当前代码所在文件的默认字符集进行编码 （UTF-8）
        byte[] bytes = name.getBytes("GBK"); // 指定GBK编码，中文两个字节
//        byte[] bytes2 = name.getBytes(StandardCharsets.UTF_8); //系统提供了方法指定编码，防止你写错
        System.out.println(bytes.length);
        System.out.println(Arrays.toString(bytes));

        // 2、解码：把字节转换成对应的中文形式（编码前 和 编码后的字符集必须一致，否则乱码 ）
//         String rs = new String(bytes); // 编码用的GBK，默认UTF-8的解码会乱码，因为识别三个字节
        String rs = new String(bytes, "GBK"); // 指定GBK解码，两个字节解析一个中文
        System.out.println(rs);
//        
        
//        Writer fzzzz = new FileWriter("D:\\JAVA学习\\文件操作\\z.txt");//追加管道
//        fzzzz.write(32343);//先转成字符，再去UTF-8的码表里找到一样字符对应的16进制编码，再转为二进制，传到目标文件
        
//      默认码表是UTF-8
//      输出时先在UTF-8的码表里找到字符对应的16进制编码，再转为二进制，传到目标文件

        

//        fzzzz.close();
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
    }
}
